package com.feng.test.ppt;

import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigInteger;
import java.util.List;
import java.util.UUID;
import javax.imageio.ImageIO;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.wmf.tosvg.WMFTranscoder;
import org.apache.poi.sl.usermodel.FillStyle;
import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.StrokeStyle;
import org.apache.poi.sl.usermodel.TableCell;
import org.apache.poi.xslf.usermodel.*;

/**
 * @author HuangSuip
 */
public class PPTXAnalyse {

    public static void main(String[] args) {
        // XSLFGraphicFrame(图表) XSLFConnectorShape（形状）XSLFGraphicFrame（组织  公式）
        //XSLFPictureShape （图片） XSLFTextBox（文本 继承autoShape） XSLFTable（表格）
        //XSLFAutoShape（标题 ）
        BigInteger integer = BigInteger.valueOf(1);
        try (InputStream inputStream = new FileInputStream(new File("E:\\ppt\\321.pptx"))) {
            XMLSlideShow slideShow = new XMLSlideShow(inputStream);
            List<XSLFSlideMaster> masterList = slideShow.getSlideMasters();
            for (XSLFSlideMaster master : masterList) {
                XSLFBackground background = master.getBackground();
                //drawSimpleShape(background);

                Rectangle2D rectangle2D = background.getAnchor();
                //drawMaster(master, rectangle2D);

/*                System.out.println("Color: "+background.getFillColor());
                System.out.println("Style: "+background.getFillStyle());*/
            }
            List<XSLFSlide> slides = slideShow.getSlides();
            int i = 1;
            for (XSLFSlide slide : slides) {
                System.out.println("========第 " + i++ + " 幻灯片=========");
                System.out.println(slide.getFollowMasterBackground());

                List<XSLFShape> shapes = slide.getShapes();
                //drawSlide(slide);
                for (XSLFShape shape : shapes) {


                    shapeAll(shape);
                    if (shape instanceof XSLFAutoShape) {
                        autoShapeAnalyse(shape);
                    }
                    if (shape instanceof XSLFConnectorShape) {
                        //connectorShapeAnalyse(shape);
                    }
                    if (shape instanceof XSLFGraphicFrame) {
                        //graphicFrame((XSLFGraphicFrame) shape);
                    }
                    if (shape instanceof XSLFFreeformShape) {
                        //drawSimpleShape((XSLFFreeformShape)shape);
                    }
                    if (shape instanceof XSLFFreeformShape) {
                        //drawSlide(slide);
                        //freeformAnalyse((XSLFFreeformShape) shape);
                    }
                    //tableProps(shape);
                    //textProps(shape);
                    //graphicFrameAnalyse(shape, slide);
                    //picAnalyse(shape);

                    System.out.println();
                }
                XSLFBackground background = slide.getBackground();

                backgroundAnalyse(background);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void shapeAll(XSLFShape shape) {
        System.out.println(
            "shapeName:" + shape.getShapeName() + "    shapeClass:" + shape.getClass() + "        shapeId: " + shape.getShapeId());
        System.out.println("left: " + shape.getAnchor().getX());
        System.out.println("top: " + shape.getAnchor().getY());
        System.out.println("height: " + shape.getAnchor().getHeight());
        System.out.println("width: " + shape.getAnchor().getWidth());
    }

    private static void drawMaster(XSLFSlideMaster master, Rectangle2D rectangle2D) {
        BufferedImage image = new BufferedImage(
            (int) rectangle2D.getWidth() + 1, (int) rectangle2D.getHeight() + 1, BufferedImage.TYPE_INT_ARGB);
        Graphics2D graphics2D = image.createGraphics();
        graphics2D.fill(new Rectangle2D.Double(0, 0, rectangle2D.getWidth(), rectangle2D.getHeight()));
        Rectangle2D rectangle2D1 = new Rectangle2D.Double(0, 0, rectangle2D.getWidth(), rectangle2D.getHeight());
        master.draw(graphics2D);
        try (FileOutputStream fos = new FileOutputStream(new File("E:\\ppt\\slide\\" + UUID.randomUUID() + ".jpg"))) {
            ImageIO.write(image, "png", fos);
            System.out.println("pic draw success");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void freeformAnalyse(XSLFFreeformShape shape) {
        drawSimpleShape(shape);
    }


    private static void graphicFrame(XSLFGraphicFrame shape) throws IOException, TranscoderException {
        XSLFPictureShape pictureShape = shape.getFallbackPicture();
        if (pictureShape == null) {
            //drawSimpleShape(shape);
            System.out.println("pictureShape is null");
            return;
        }
        System.out.println("shapeType: " + shape.getXmlObject());
        InputStream inputStream = pictureShape.getPictureData().getInputStream();
        FileOutputStream fos = new FileOutputStream(
            new File("E:\\ppt\\slide\\" + shape.getShapeName() + UUID.randomUUID() + ".svg"));
        WMFTranscoder transcoder = new WMFTranscoder();
        //ByteArrayInputStream bais = new ByteArrayInputStream()
        TranscoderInput input = new TranscoderInput(inputStream);
        TranscoderOutput output = new TranscoderOutput(fos);
        transcoder.transcode(input, output);

        int len;
        byte[] b = new byte[1024];
        while ((len = inputStream.read(b)) != -1) {
            fos.write(b, 0, len);
            fos.flush();
        }

        fos.close();
        inputStream.close();

        System.out.println();
        System.out.println();
    }

    private static void connectorShapeAnalyse(XSLFShape shape) {
        XSLFConnectorShape connectorShape = (XSLFConnectorShape) shape;
        connectorShape.getHyperlink();//超链接

        System.out.println(connectorShape.getLineCap());
        //drawSimpleShape(connectorShape);
    }

    private static void autoShapeAnalyse(XSLFShape shape) {
        XSLFTextBox autoShape = (XSLFTextBox) shape;
/*        if (autoShape instanceof XSLFTextBox) {
            return;
        }*/
        System.out.println("shapeId: " + autoShape.getShapeId() + "   shapeName: " + autoShape.getShapeName());
        System.out.println("shapeType: " + autoShape.getShapeType());
        System.out.println("Text: " + autoShape.getText());
        System.out.println("Color: " + autoShape.getFillColor());
        List<XSLFTextParagraph> list = autoShape.getTextParagraphs();
        System.out.println("size: " + list.size());
        list.forEach(p -> {
            System.out.println("content: " + p.getText());
            System.out.println("text size: " + p.getTextRuns().size());
            System.out.println("lineSpacing: " + p.getLineSpacing());
            System.out.println(p.getSpaceAfter());
            p.getTextRuns().forEach(run -> {
                System.out.println(run.getRawText());
                double line = run.getCharacterSpacing()/run.getFontSize();
            });
        });
        //System.out.println(autoShape.getXmlObject());
/*        if (true) {
            List<XSLFTextParagraph> paragraphs = autoShape.getTextParagraphs();
            for (XSLFTextParagraph paragraph : paragraphs) {
                List<XSLFTextRun> runList = paragraph.getTextRuns();
                for (XSLFTextRun run : runList) {
                    run.setFontFamily("宋体");
                }
            }
        }
        drawSimpleShape(autoShape);*/
    }

    private static void backgroundAnalyse(XSLFBackground shape) {
        System.out.println("background color: " + shape.getFillColor());
        FillStyle fillStyle = shape.getFillStyle();
        if (fillStyle instanceof XSLFSimpleShape) {
            System.out.println("fill type: " + shape.getFillStyle());
        }

        System.out.println(shape.getClass());
        //drawSimpleShape(shape);
    }

    private static void picAnalyse(XSLFShape shape) throws IOException {
        if (shape instanceof XSLFPictureShape) {
            XSLFPictureShape pictureShape = (XSLFPictureShape) shape;
            System.out.println(pictureShape.getRotation());
            System.out.println(pictureShape.getFlipVertical());
            System.out.println(pictureShape.getFlipHorizontal());
            System.out.println(pictureShape.getLineColor());
            System.out.println(pictureShape.getLineWidth());
            System.out.println(pictureShape.getLineCompound());
            System.out.println(pictureShape.getLineDecoration());
            System.out.println(pictureShape.getLineDash());//短划线

            InputStream inputStream = pictureShape.getPictureData().getInputStream();
            FileOutputStream fos = new FileOutputStream(
                new File("E:\\ppt\\slide\\" + shape.getShapeName() + UUID.randomUUID() + ".jpg"));
            int len = 0;
            byte[] b = new byte[1024];
            while ((len = inputStream.read(b)) != -1) {
                fos.write(b, 0, len);
            }
            fos.close();
            inputStream.close();
            //drawSimpleShape(shape);
        }
    }

    private static void drawSimpleShape(XSLFSimpleShape shape) {
        Rectangle2D rectangle2D = shape.getAnchor();
        BufferedImage image = new BufferedImage(
            (int) rectangle2D.getWidth() + 1, (int) rectangle2D.getHeight() + 1, BufferedImage.TYPE_INT_ARGB);
        Graphics2D graphics2D = image.createGraphics();

/*        image = graphics2D.getDeviceConfiguration().createCompatibleImage( (int)rectangle2D.getWidth(), (int) rectangle2D.getHeight(), Transparency.TRANSLUCENT);
        graphics2D.dispose();
        graphics2D = image.createGraphics();*/
        graphics2D.fill(new Rectangle2D.Double(0, 0, rectangle2D.getWidth(), rectangle2D.getHeight()));
        //图片旋转
        Rectangle2D rectangle2D1 = new Rectangle2D.Double(0, 0, rectangle2D.getWidth(), rectangle2D.getHeight());
        shape.draw(graphics2D, rectangle2D1);
        try (FileOutputStream fos = new FileOutputStream(new File("E:\\ppt\\slide\\" + UUID.randomUUID() + ".jpg"))) {
            ImageIO.write(image, "png", fos);
            System.out.println("pic draw success");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    private static void drawSlide(XSLFSlide slide) {
        Dimension dimension = slide.getSlideShow().getPageSize();
        BufferedImage image = new BufferedImage(
            (int) dimension.getWidth(), (int) dimension.getHeight(), BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics2D = image.createGraphics();
        graphics2D.fill(new Rectangle2D.Double(0, 0, dimension.getWidth(), dimension.getHeight()));
        slide.draw(graphics2D);
        try (FileOutputStream fos = new FileOutputStream(new File("E:\\ppt\\slide\\" + UUID.randomUUID() + ".png"))) {
            ImageIO.write(image, "png", fos);
            System.out.println("slide draw success");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void graphicFrameAnalyse(XSLFShape shape, XSLFSlide slide) {
        if (shape instanceof XSLFTable) {
            //XSLFGraphicFrame frame = (XSLFGraphicFrame) shape;
            XSLFTable frame = (XSLFTable) shape;
/*            XSLFPictureShape pictureShape = frame.getFallbackPicture();
            System.out.println(pictureShape);*/
            Rectangle2D rectangle2D = frame.getAnchor();
            BufferedImage image = new BufferedImage(
                (int) rectangle2D.getWidth() * 3, (int) rectangle2D.getHeight() * 3, BufferedImage.TYPE_INT_RGB);
            //BufferedImage image = new BufferedImage(1000,1000, BufferedImage.TYPE_INT_ARGB);
            Graphics2D graphics2D = image.createGraphics();
            graphics2D.setBackground(Color.white);
            graphics2D.fill(new Rectangle2D.Double(0, 0, rectangle2D.getWidth(), rectangle2D.getHeight()));
            //graphics2D.fill(rectangle2D);
            Rectangle2D rectangle2D1 = new Rectangle2D.Double(0, 0, rectangle2D.getWidth(), rectangle2D.getHeight());
            frame.draw(graphics2D, rectangle2D1);
            try (FileOutputStream fos = new FileOutputStream(
                new File("E:\\ppt\\slide\\" + frame.getShapeName() + UUID.randomUUID() + ".png"))) {
                ImageIO.write(image, "png", fos);
                System.out.println("frame draw success");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private static void tableProps(XSLFShape shape) throws IOException {
        if (shape instanceof XSLFTable) {
            XSLFTable table = (XSLFTable) shape;
            //System.out.println(frame.getCTTable());
            System.out.println("rows: " + table.getNumberOfRows());
            XSLFPictureShape shape1 = table.getFallbackPicture();
            //System.out.println("PIC:"+ shape1);
            System.out.println(table.getCell(0, 0).getText());
            picAnalyse(shape1);
            List<XSLFTableRow> tableRows = table.getRows();

            for (XSLFTableRow row : tableRows) {
                System.out.println("++++++++一行开始++++++++");
                System.out.println();
                for (int i = 0; i < row.getCells().size(); i++) {
                    XSLFTableCell cell = row.getCells().get(i);
                    System.out.println("第" + i + "个单元格: span:" + cell.getRowSpan());
                    System.out.println("单元格跨度：" + cell.getGridSpan());
                    System.out.println("单元格文字：" + cell.getText());
                    System.out.println("单元格文字方向：" + cell.getVerticalAlignment());
                    System.out.println("单元格宽高：" + cell.getAnchor().getWidth() + "   " + cell.getAnchor().getHeight());
                    System.out.println(cell.isMerged());

                    StringBuilder sb = new StringBuilder();
                    StrokeStyle rightStrokeStyle = cell.getBorderStyle(TableCell.BorderEdge.right);
                    StrokeStyle leftStrokeStyle = cell.getBorderStyle(TableCell.BorderEdge.left);
                    StrokeStyle botStrokeStyle = cell.getBorderStyle(TableCell.BorderEdge.bottom);
                    StrokeStyle topStrokeStyle = cell.getBorderStyle(TableCell.BorderEdge.top);
                    if (rightStrokeStyle != null) {
                        Color color = ((PaintStyle.SolidPaint) rightStrokeStyle.getPaint()).getSolidColor().getColor();
                        sb.append(
                            "border-right:3px solid rgb(" + color.getRed() + "," + color.getGreen() + "," + color.getBlue() + ");");
                    }
                    if (leftStrokeStyle != null) {
                        Color color = ((PaintStyle.SolidPaint) leftStrokeStyle.getPaint()).getSolidColor().getColor();
                        sb.append(
                            "border-left:3px solid rgb(" + color.getRed() + "," + color.getGreen() + "," + color.getBlue() + ");");
                    }
                    if (botStrokeStyle != null) {
                        Color color = ((PaintStyle.SolidPaint) botStrokeStyle.getPaint()).getSolidColor().getColor();
                        sb.append(
                            "border-bottom:3px solid rgb(" + color.getRed() + "," + color.getGreen() + "," + color.getBlue() + ");");
                    }
                    if (topStrokeStyle != null) {
                        Color color = ((PaintStyle.SolidPaint) topStrokeStyle.getPaint()).getSolidColor().getColor();
                        sb.append(
                            "border-top:3px solid rgb(" + color.getRed() + "," + color.getGreen() + "," + color.getBlue() + ");");
                    }
                    System.out.println(sb.toString());
                }

                System.out.println("++++++++一行结束++++++++");
            }
        }
    }

    private static void textProps(XSLFShape shape) {
        if (shape instanceof XSLFAutoShape) {
            System.out.println(shape.getClass());
            if (shape instanceof XSLFTextBox) {
                XSLFTextBox textBox = (XSLFTextBox) shape;
/*                System.out.println(textBox.getText());
                System.out.println(textBox.getTextPlaceholder());
                System.out.println(textBox.getFlipHorizontal());
                System.out.println(textBox.getFlipVertical());
                System.out.println(textBox.getBottomInset());
                System.out.println(textBox.getTextAutofit());
                System.out.println(textBox);*/
                System.out.println("碎片类型: " + textBox.getShapeType());
                //获取对齐方式  非文字！！
                System.out.println("垂直对齐方式:  " + textBox.getVerticalAlignment());
                System.out.println("文字方向: " + textBox.getTextDirection());
                //System.out.println(textBox.getXmlObject());
                for (XSLFTextParagraph paragraph : textBox.getTextParagraphs()) {
                    System.out.println("============段落开始=========");
                    //System.out.println(paragraph.getBulletFont());
                    //System.out.println("getBulletFontSize: "+paragraph.getBulletFontSize()); //null
                    //System.out.println(paragraph.getIndentLevel());
                    //System.out.println("text run :"+paragraph.getTextRuns());
                    //System.out.println("getFontAlign: "+paragraph.getFontAlign());
                    System.out.println("文字局向: " + paragraph.getTextAlign());
                    System.out.println(paragraph.getText());
                    List<XSLFTextRun> runList = paragraph.getTextRuns();
                    for (XSLFTextRun run : runList) {
                        System.out.println("++++++++++++一段文字开始+++++++++++");
                        System.out.println("size: " + run.getFontSize());
                        Color color = ((PaintStyle.SolidPaint) run.getFontColor()).getSolidColor().getColor();
                        System.out.println("color: " + color.getRed() + "," + color.getGreen() + "," + color.getBlue());
                        if (run.getFontColor() instanceof PaintStyle.SolidPaint) {
                            System.out.println(true);
                        } else {
                            System.out.println(false);
                        }
                        System.out.println("text: " + run.getRawText());
                        System.out.println("字体：" + run.getFontFamily());
                        //Bold加粗 Italic 倾斜 Underlined 下划线 Subscript下标
                        //getCharacterSpacing()  间距
                        System.out.println(run.isBold());
                        //System.out.println("getHyperlink: "+run.getHyperlink()); //null
                        //System.out.println(run.getFieldType());
                        //System.out.println(run.getHyperlink());
                        System.out.println("++++++++++++一段文字结束+++++++++++");
                    }
                    //System.out.println(paragraph.getText());
                    System.out.println("============段落结束=========");
                }
            } /*else if (shape instanceof XSLFFreeformShape) {
                XSLFFreeformShape freeformShape = (XSLFFreeformShape) shape;
                System.out.println(freeformShape.getText());
            } */ else {
                XSLFAutoShape autoShape = (XSLFAutoShape) shape;
                System.out.println(autoShape.getText());
            }
        } else {
            System.out.println(shape.getClass() + shape.getShapeName());
        }
    }
}
/*                CTSlide xmlObject = slide.getXmlObject();
                CTGroupShape spTree = xmlObject.getCSld().getSpTree();
                CTShape[] spArray = spTree.getSpArray();
                for (CTShape shape : spArray) {
                    CTTextBody txBody = shape.getTxBody();
                    if(txBody == null){
                        continue;
                    }
                    CTTextParagraph[] pArray = txBody.getPArray();
                    CTTextFont font=CTTextFont.Factory.parse(
                            "<xml-fragment xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\">"+
                                    "<a:rPr lang=\"zh-CN\" altLang=\"en-US\" dirty=\"0\" smtClean=\"0\"> "+
                                    "<a:latin typeface=\"+mj-ea\"/> "+
                                    "</a:rPr>"+
                                    "</xml-fragment>");
                    for (CTTextParagraph textParagraph : pArray) {
                        CTRegularTextRun[] textRuns = textParagraph.getRArray();
                        for (CTRegularTextRun textRun : textRuns) {
                            CTTextCharacterProperties properties=textRun.getRPr();
                            properties.setLatin(font);
                        }
                    }
                }*/

/*                XSLFBackground background = slide.getBackground();
                FillStyle fillStyle = background.getFillStyle();
                System.out.println(background);
                Rectangle2D rectangle2D = background.getAnchor();
                BufferedImage image = new BufferedImage((int) rectangle2D.getWidth() + 1, (int) rectangle2D.getHeight() + 1, BufferedImage.TYPE_INT_RGB);
                //BufferedImage image = new BufferedImage(1000,1000, BufferedImage.TYPE_INT_ARGB);
                Graphics2D graphics2D = image.createGraphics();
                graphics2D.setBackground(Color.white);
                graphics2D.fill(new Rectangle2D.Double(0, 0, rectangle2D.getWidth(), rectangle2D.getHeight()));
                background.draw(graphics2D , rectangle2D);
                try (FileOutputStream fos = new FileOutputStream(new File("E:\\ppt\\slide\\" + UUID.randomUUID() + ".jpg" ))) {
                    ImageIO.write(image, "png", fos);
                    System.out.println("pic draw success");
                } catch (IOException e) {
                    e.printStackTrace();
                }*/


/*                    if (shape instanceof  XSLFTextShape){
                        XSLFTextShape tsh = (XSLFTextShape)shape;
                        for(XSLFTextParagraph p : tsh){
                            for(XSLFTextRun r : p){
                                r.setFontFamily("宋体");
                            }
                        }
                    }*/
